package com.gpframework.framework.logging;

import com.gpframework.common.constant.HttpStatus;
import com.gpframework.common.core.domain.AjaxResult;
import com.gpframework.common.utils.StringUtils;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.json.HTTP;
import org.springframework.stereotype.Component;
import org.springframework.util.StopWatch;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import reactor.core.publisher.Flux;

import javax.servlet.http.HttpServletRequest;
import java.text.DecimalFormat;
import java.text.MessageFormat;
import java.util.Arrays;
import java.util.Enumeration;
import java.util.Map;

/**
 * @author zhuzhiou
 * @date 2021/1/30 21:05
 */
@Component
@Aspect
@Slf4j
public class LogMonitorAspect {

    private static final ThreadLocal<String> resquestId = ThreadLocal.withInitial(RandomStringUtils::uniqueRandom);

    private static final ThreadLocal<Long> elapse = ThreadLocal.withInitial(System::currentTimeMillis);

   // private IGpAppMemberService iGpAppMemberService;

   // public LogMonitorAspect(IGpAppMemberService iGpAppMemberService) {
     //   this.iGpAppMemberService = iGpAppMemberService;
    //}

    //@Pointcut("@annotation(org.springframework.web.bind.annotation.GetMapping) || @annotation(org.springframework.web.bind.annotation.PostMapping)")
    @Pointcut("within(@org.springframework.web.bind.annotation.RestController *)")
    public void logMonitorPointCut() {
    }

    /**
     * 输出格式：
     */
    @Around("logMonitorPointCut()")
    public Object logMonitorAround(ProceedingJoinPoint joinPoint) throws Throwable {
        if (!log.isInfoEnabled()) {
            return joinPoint.proceed();
        }
        StopWatch stopWatch = new StopWatch();
        Object response;
        try {
            stopWatch.start();
            response = joinPoint.proceed();
        } finally {
            if (stopWatch.isRunning()) {
                stopWatch.stop();
            }
        }
        Object argsInfo = "";
        Object[] args = joinPoint.getArgs();
        if (args.length>0){
            argsInfo = args[0];
        }
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = attributes.getRequest();
        DecimalFormat decimalFormat = new DecimalFormat("#.##");
        Enumeration<String> headerNames=request.getHeaderNames();
        StringBuffer sbf = new StringBuffer();
        for(Enumeration<String> e=headerNames;e.hasMoreElements();){
            String thisName=e.nextElement();
            String thisValue=request.getHeader(thisName);
            sbf.append(thisName+":"+thisValue+";");
        }
        StringBuilder sb = new StringBuilder();
        // 记录下请求内容
        sb.append("\r\n****************************Start[{0}]**************************************");
        sb.append("\r\n REQUEST_HEADERS : {1}");
        sb.append("\r\n ARGS : {2}");
        sb.append("\r\n URL : {3}");
        sb.append("\r\n ELAPSETIME : {4}");
        sb.append("\r\n RESPONSE : {5}");
        sb.append("\r\n****************************End[{6}]**************************************");
        String loginToken = request.getHeader("loginToken");
        String memberId = request.getHeader("memberId");
        //身份token校验
        /*if (StringUtils.isNotBlank(loginToken) && StringUtils.isNotBlank(memberId)){
            AjaxResult ajaxResult = iGpAppMemberService.checkToken(loginToken, memberId);
            if (ajaxResult.getCode() == HttpStatus.FORBIDDEN){
                response = ajaxResult;
            }
        }*/
        String info = MessageFormat.format(sb.toString(), resquestId.get(), sbf.toString(),argsInfo,
                request.getRequestURI(),decimalFormat.format(stopWatch.getTotalTimeSeconds()),
                response, resquestId.get());
        log.info(info);

        /*Enumeration<String> headerNames=request.getHeaderNames();
        StringBuffer sbf = new StringBuffer();
        for(Enumeration<String> e=headerNames;e.hasMoreElements();){
            String thisName=e.nextElement();
            String thisValue=request.getHeader(thisName);
            sbf.append(thisName+":"+thisValue+";");
        }
        log.debug("LOGID:{} ; ARGS: {}",resquestId.get(), joinPoint.getArgs());
        log.debug("LOGID:{} ; REQUEST_HEADERS: {}",resquestId.get(), sbf.toString());
        String loginToken = request.getHeader("loginToken");
        String memberId = request.getHeader("memberId");
        log.debug("LOGID:{} ; URL: {} ; ELAPSETIME: {} ; LOGINTOKEN: {} ; MEMBERID: {}",resquestId.get(), request.getRequestURI(),decimalFormat.format(stopWatch.getTotalTimeSeconds()),loginToken,memberId);
        //身份token校验
        if (StringUtils.isNotBlank(loginToken) && StringUtils.isNotBlank(memberId)){
            AjaxResult ajaxResult = iGpAppMemberService.checkToken(loginToken, memberId);
            if (ajaxResult.getCode() == HttpStatus.FORBIDDEN){
                response = ajaxResult;
            }
        }
        log.debug("LOGID:{} ; RESPONSE: {}", resquestId.get(),response);*/

        resquestId.remove();
        return response;
    }
}
